#ifndef _TCPCONNECTION_
#define _TCPCONNECTION_

#include "noncopyable.h"
#include "InetAddress.h"
#include "Callback.h"
#include "Buffer.h"
#include "Timestamp.h"

#include <memory>
#include <string>
#include <atomic>

class Channel;
class EventLoop;
class Socket;

/*
    有一个新用户连接，通过accept函数获取connfd -> Acceptor -> TcpServer
    TcpServer->TcpConnection->Channel，然后Poller监听channel，当channel有事件发生会触发回调
*/

size_t HIGHWATERMARK = 64 * 1024 * 1024;

class TcpConnection : noncopyable, public std::enable_shared_from_this<TcpConnection>
{
public:
    TcpConnection(EventLoop *loop
        , const std::string& name
        , int sockfd
        , const InetAddress& localAddr
        , const InetAddress& peerAddr);
    ~TcpConnection();

    EventLoop* getLoop() const { return loop_; }
    const std::string& name() const { return name_; }
    const InetAddress& localAddr() const { return localAddr_; }
    const InetAddress& peerAddr() const { return peerAddr_; }
    
    bool connected() const { return state_ == kConnected; }
    
    //void send(std::string& message, int len);
    void send(const void* message, int len);
    void shutdown();    //关闭当前连接

    void setConnectionCallback(const ConnectionCallback& cb)    { connectionCallback_ = cb; }
    void setMessageCallback(const MessageCallback& cb)  { messageCallback_ = cb; }
    void setWriteCallback(const WriteCallback& cb)  { writeCallback_ = cb; }
    void setCloseCallback(const CloseCallback& cb)  { closeCallback_ = cb; }

    void connectEstablished();
    void connectDestroyed();

    void handleRead(Timestamp);
    void handleWrite();
    void handleClose();
    void handleError();

    void sendInLoop(const void *message, int len);
    void shutdownInLoop();
private:
    enum StateE { kConnecting, kConnected, kDisConnecting, kDisconnected };
    EventLoop *loop_;   //这里不是Baseloop,因为TcpConnect都是给已经建立好tcp连接的。也就是都是在SubLoop中管理的
    const std::string name_;
    std::atomic_int state_;
    bool reading_;

    //这里和Acceptor（在baseLoop）差不多，而TCPConnection（subLoop）
    std::unique_ptr<Socket> socket_;
    std::unique_ptr<Channel> channel_;

    const InetAddress localAddr_;           //当前主机
    const InetAddress peerAddr_;            //对端
    ConnectionCallback connectionCallback_;      
    MessageCallback messageCallback_;
    WriteCallback writeCallback_;
    HighWaterMarkCallback highWaterMarkCallback_;
    CloseCallback closeCallback_;

    size_t highWaterMark_;
    Buffer inputBuffer_;
    Buffer outputBuffer_;
};

#endif